package com.next.aap.server.persistance.helper;

import java.util.List;

import org.springframework.stereotype.Component;

import com.next.aap.server.persistance.District;
import com.next.core.db.page.PageInfo;
import com.next.core.db.page.PageResult;
import com.next.core.db.page.QueryParam;
import com.next.core.db.validator.ObjectValidator;
import com.next.core.exception.AppException;
import com.next.ext.core.db.page.HibernateQueryParamPageInfo;
import com.next.ext.core.db.page.HibernateQueryParamPageInfo.ORDER;
import com.next.ext.core.persistance.dao.BasePersistanceDao;

@Component
public class DistrictHelper extends BasePersistanceDao<District> implements ObjectValidator<District> {

	/**
	 * Creates/updates a district in Database
	 * 
	 * @param district
	 * @return saved district
	 * @throws AppException
	 */
	public District saveDistrict(District district) throws AppException
	{
		checkIfDistrictExistsWithSameName(district);
		district.setNameUp(district.getName().toUpperCase());
		district = super.saveObject(district);
		return district;
	}

	/**
	 * deletes a district in Database
	 * 
	 * @param district
	 * @return updated district
	 * @throws AppException
	 */
	public void deleteDistrict(District district) throws AppException {
		super.deleteObject(district);
	}

	/**
	 * return a District with given primary key/id
	 * 
	 * @param id
	 * @return District with PK as id(parameter)
	 * @throws AppException
	 */
	public District getDistrictById(Long id) throws AppException
	{
		District district = super.getObjectByPK(District.class, id);
		return district;
	}

	/**
	 * @param pageInfo
	 * @return search result
	 * @throws AppException
	 */
	public PageResult<District> searchDistricts(PageInfo pageInfo) throws AppException
	{
		return super.findObject(District.class, pageInfo);
	}

	public List<District> getAllDistricts() throws AppException
	{
		PageInfo pageInfo = null;
		return super.findObject(District.class, pageInfo).getResultList();
	}
	public List<District> getDistrictOfState(long stateId) throws AppException{
		HibernateQueryParamPageInfo pageInfo = new HibernateQueryParamPageInfo();
		QueryParam stateQueryParam = new QueryParam();
		stateQueryParam.setCaseSenstive(false);
		stateQueryParam.setField("stateId");
		stateQueryParam.setFieldType(QueryParam.FIELD_TYPE_NUMBER);
		stateQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		stateQueryParam.setValue(stateId);
		pageInfo.addCriteria(stateQueryParam);
		
		pageInfo.addOrderBy("name", ORDER.ASC);
		
		PageResult<District> pr = this.searchDistricts(pageInfo);
		List<District> districtList = pr.getResultList();
		return districtList;
	}

	public void validateObjectForCreate(District district) throws AppException {
		checkIfStringMissing("Name", district.getName());
		checkIfObjectMissing("State", district.getState());
	}

	public void validateObjectForUpdate(District district) throws AppException {
		checkIfStringMissing("Name", district.getName());
		checkIfObjectMissing("State", district.getState());
	}
	private void checkIfDistrictExistsWithSameName(District district) throws AppException{
		HibernateQueryParamPageInfo pageInfo = new HibernateQueryParamPageInfo();
		QueryParam emailQueryParam = new QueryParam();
		emailQueryParam.setCaseSenstive(false);
		emailQueryParam.setField("nameUp");
		emailQueryParam.setFieldType(QueryParam.FIELD_TYPE_STRING);
		emailQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		emailQueryParam.setValue(district.getName().toUpperCase());
		pageInfo.addCriteria(emailQueryParam);
		
		QueryParam stateQueryParam = new QueryParam();
		stateQueryParam.setField("stateId");
		stateQueryParam.setFieldType(QueryParam.FIELD_TYPE_NUMBER);
		stateQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		stateQueryParam.setValue(district.getState().getId());
		pageInfo.addCriteria(stateQueryParam);
		
		if(district.getId() != null && district.getId() > 0){
			QueryParam districtIdQueryParam = new QueryParam();
			districtIdQueryParam.setCaseSenstive(false);
			districtIdQueryParam.setField("id");
			districtIdQueryParam.setFieldType(QueryParam.FIELD_TYPE_NUMBER);
			districtIdQueryParam.setOperator(QueryParam.OPERATOR_NOT_EQUAL);
			districtIdQueryParam.setValue(district.getId());
			pageInfo.addCriteria(districtIdQueryParam);
		}
		
		PageResult<District> pr = this.searchDistricts(pageInfo);
		if(pr.getResultList().size() > 0){
			throw new AppException("District already exists with name = "+district.getName()+" in state "+district.getState().getName());
		}
	}
}